<i18n locale="zh-CN" lang="yaml">
Add ENV  : 添加环境变量
Setup ENV: 配置环境变量

Value Type: 值类型
Invalid Integer value: 整数格式不正确
Invalid Float value  : 浮点数格式不正确
Invalid Boolean value: 布尔值格式不正确
Invalid JSON value   : JSON 格式不正确

Please input ID: 请输入 ID
Only alphabets, numbers and underscore are allowed: 只能包含大小写英文、数字及下划线
Cannot not starts with a number: 不得以数字开头
Please input Value: 请输入值

Leave blank when not changing: 不修改时请留空

ENV Variable created: 环境变量已创建
ENV Variable saved  : 环境变量已保存
ENV Variable deleted: 环境变量已删除

Are you sure you want to delete the ENV?: 是否确认删除此环境变量？
</i18n>

<!-- Generated by OpenCC START -->
<i18n locale="zh-HK" lang="yaml">
Add ENV: 添加環境變量
Are you sure you want to delete the ENV?: 是否確認刪除此環境變量？
Cannot not starts with a number: 不得以數字開頭
ENV Variable created: 環境變量已創建
ENV Variable deleted: 環境變量已刪除
ENV Variable saved: 環境變量已保存
Invalid Boolean value: 布爾值格式不正確
Invalid Float value: 浮點數格式不正確
Invalid Integer value: 整數格式不正確
Invalid JSON value: JSON 格式不正確
Leave blank when not changing: 不修改時請留空
Only alphabets, numbers and underscore are allowed: 只能包含大小寫英文、數字及下劃線
Please input ID: 請輸入 ID
Please input Value: 請輸入值
Setup ENV: 配置環境變量
Value Type: 值類型
</i18n>
<i18n locale="zh-TW" lang="yaml">
Add ENV: 新增環境變數
Are you sure you want to delete the ENV?: 是否確認刪除此環境變數？
Cannot not starts with a number: 不得以數字開頭
ENV Variable created: 環境變數已建立
ENV Variable deleted: 環境變數已刪除
ENV Variable saved: 環境變數已儲存
Invalid Boolean value: 布林值格式不正確
Invalid Float value: 浮點數格式不正確
Invalid Integer value: 整數格式不正確
Invalid JSON value: JSON 格式不正確
Leave blank when not changing: 不修改時請留空
Only alphabets, numbers and underscore are allowed: 只能包含大小寫英文、數字及下劃線
Please input ID: 請輸入 ID
Please input Value: 請輸入值
Setup ENV: 配置環境變數
Value Type: 值型別
</i18n>
<!-- Generated by OpenCC END -->

<template>
  <el-dialog
    id="ScriptSetSetup"
    :visible.sync="show"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    width="750px">

    <template slot="title">
      {{ pageTitle }} <code class="text-main" v-if="pageMode === 'setup'">{{ data.title || data.id }}</code>
    </template>

    <el-container direction="vertical">
      <el-main>
        <div class="setup-form">
          <el-form ref="form" label-width="135px" :model="form" :rules="formRules">
            <el-form-item label="ID" prop="id">
              <el-input :disabled="pageMode === 'setup'"
                maxlength="60"
                v-model="form.id"></el-input>
            </el-form-item>

            <el-form-item :label="$t('Title')">
              <el-input :placeholder="$t('Optional')"
                maxlength="200"
                v-model="form.title"></el-input>
            </el-form-item>

            <el-form-item :label="$t('Description')">
              <el-input :placeholder="$t('Optional')"
                type="textarea"
                resize="none"
                :autosize="{minRows: 2}"
                maxlength="5000"
                v-model="form.description"></el-input>
            </el-form-item>

            <el-form-item :label="$t('Value Type')">
              <el-select v-model="form.autoTypeCasting" @change="switchAutoTypeCasting">
                <el-option v-for="opt in C.ENV_VARIABLE" :label="opt.name" :key="opt.key" :value="opt.key"></el-option>
              </el-select>
              <InfoBlock v-if="C.ENV_VARIABLE_MAP.get(form.autoTypeCasting)"
                :title="C.ENV_VARIABLE_MAP.get(form.autoTypeCasting).tips" />
            </el-form-item>

            <el-form-item :label="$t('Value')" prop="valueTEXT">
              <el-input
                :type="form.autoTypeCasting === 'password' ? null : 'textarea'"
                :show-password="form.autoTypeCasting === 'password'"
                :placeholder="pageMode === 'setup' && form.autoTypeCasting === 'password' ? $t('Leave blank when not changing') : ''"
                resize="none"
                :autosize="{minRows: 3}"
                maxlength="5000"
                @blur="formatValue"
                v-model="form.valueTEXT"></el-input>
            </el-form-item>

            <el-form-item class="setup-footer">
              <el-link type="danger" class="float-left" v-if="pageMode === 'setup'" @click="deleteData">{{ $t('Delete') }}</el-link>
              <el-button type="primary" v-prevent-re-click @click="submitData">{{ $t('Save') }}</el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-main>
    </el-container>
  </el-dialog>
</template>

<script>
export default {
  name: 'EnvVariableSetup',
  components: {
  },
  watch: {
    show(val) {
      if (val && this.$refs.form) {
        this.$refs.form.clearValidate();
      }
    },
  },
  methods: {
    updateValidator(autoTypeCasting) {
      if (this.$refs.form) this.$refs.form.clearValidate();

      let isSetupPassword = this.pageMode === 'setup' && autoTypeCasting === 'password';
      this.formRules.valueTEXT[0].required = !isSetupPassword;
    },
    switchAutoTypeCasting(autoTypeCasting) {
      console.log('in @change, now =', this.form.autoTypeCasting)
      this.updateValidator(autoTypeCasting);
    },

    async loadData(id) {
      if (!id) {
        this.pageMode = 'add';
        this.T.jsonClear(this.form);
        this.data = {};

        this.form.autoTypeCasting = 'string';

      } else {
        this.pageMode = 'setup';
        this.data.id = id;

        let apiRes = await this.T.callAPI_getOne('/api/v1/env-variables/do/list', this.data.id);
        if (!apiRes || !apiRes.ok) return;

        this.data = apiRes.data;

        let nextForm = {};
        Object.keys(this.form).forEach(f => nextForm[f] = this.data[f]);
        this.form = nextForm;

        this.updateValidator(this.data.autoTypeCasting);
      }

      this.show = true;
    },
    async submitData() {
      try {
        await this.$refs.form.validate();
      } catch(err) {
        return console.error(err);
      }

      switch(this.pageMode) {
        case 'add':
          return await this.addData();
        case 'setup':
          return await this.modifyData();
      }
    },
    async addData() {
      let apiRes = await this.T.callAPI('post', '/api/v1/env-variables/do/add', {
        body    : { data: this.T.jsonCopy(this.form) },
        feedback: { okMessage: this.$t('ENV Variable created') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateEnvVariableListSyncTime');
      this.show = false;
    },
    async modifyData() {
      let _formData = this.T.jsonCopy(this.form);
      delete _formData.id;

      let apiRes = await this.T.callAPI('post', '/api/v1/env-variables/:id/do/modify', {
        params  : { id: this.data.id },
        body    : { data: _formData },
        feedback: { okMessage: this.$t('ENV Variable saved') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateEnvVariableListSyncTime');
      this.show = false;
    },
    async deleteData() {
      if (!await this.T.confirm(this.$t('Are you sure you want to delete the ENV?'))) return;

      let apiRes = await this.T.callAPI('/api/v1/env-variables/:id/do/delete', {
        params  : { id: this.data.id },
        feedback: { okMessage: this.$t('ENV Variable deleted') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateEnvVariableListSyncTime');
      this.show = false;
    },
    formatValue() {
      switch(this.form.autoTypeCasting) {
        case 'json':
          try {
            let obj = JSON.parse(this.form.valueTEXT);
            this.form.valueTEXT = JSON.stringify(obj, null, 2);
          } catch(_) {
            // Nope
          }
          break;
      }
    },
  },
  computed: {
    pageTitle() {
      const _map = {
        setup: this.$t('Setup ENV'),
        add  : this.$t('Add ENV'),
      };
      return _map[this.pageMode];
    },
  },
  props: {
  },
  data() {
    return {
      show    : false,
      pageMode: null,

      data: {},
      form: {
        id             : null,
        title          : null,
        description    : null,
        autoTypeCasting: null,
        valueTEXT      : null,
      },
      formRules: {
        id: [
          {
            trigger : 'blur',
            message : this.$t('Please input ID'),
            required: true,
          },
          {
            trigger: 'change',
            message: this.$t('Only alphabets, numbers and underscore are allowed'),
            pattern: /^[a-zA-Z0-9_]*$/g,
          },
          {
            trigger: 'change',
            message: this.$t('Cannot not starts with a number'),
            pattern: /^[^0-9]/g,
          },
        ],
        valueTEXT: [
          {
            trigger : 'blur',
            message : this.$t('Please input Value'),
            required: true,
          },
          {
            trigger: 'change',
            validator: (rule, value, callback) => {
              switch(this.form.autoTypeCasting) {
                case 'integer':
                  if (!this.validator.isInt(value)) {
                    return callback(new Error(this.$t('Invalid Integer value')));
                  }
                  break;

                case 'float':
                  if (!this.validator.isFloat(value)) {
                    return callback(new Error(this.$t('Invalid Float value')));
                  }
                  break;

                case 'boolean':
                  if (this.T.toBoolean(value) === null) {
                    return callback(new Error(this.$t('Invalid Boolean value')));
                  }
                  break;

                case 'json':
                  try { JSON.parse(value) } catch(err) {
                    return callback(new Error(this.$t('Invalid JSON value')));
                  }
                  break;
              }

              return callback();
            },
          },
        ]
      },
    }
  },
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>
